///<reference path='../../index.d.ts'/>
import pdfjs from "pdfjs-dist"
import {orderBy} from "lodash"
// import worker from "pdfjs-dist/lib/pdf.worker.js"
// pdfjs.GlobalWorkerOptions.workerSrc = ''
// import 'pdfjs-dist/build/pdf.worker'

/**
 * 解析pdf类
 * @class CddPdf
 */
export default class CddPdf {
  /**要预览的文件，一般用于本地文件转换 */
  file?: File
  /**网络pdf文件地址，仅支持流下载的接口 */
  url?: string
  /**解析后的图片地址 */
  imgs: string[] = []
  /**Promise属性 */
  promise?: Promise<any>
  /**Blob url与否，如果不是则是objectUrl */
  isBlobUrl?: boolean = false
  /**配置选项 */
  options = {
    /**伸缩质量 */
    scale: 2
  }

  /**
   * 构造函数
   * @constructor 构造函数
   * @param {Object} params 参数
   * @param params.options 配置
   */
  constructor (params: {
    /**文件 */
    file?: File,
    /**流地址 */
    url?: string,
    /**是否是blob url */
    isBlobUrl?: boolean,
    /**选项 */
    options?: {
      /**放大质量，默认是2 */
      scale?: number
    }
  }) {
    if (!params) {
      throw new Error(`缺少参数 file 或者 url`)
    } else {
      this.file = params.file
      this.url = params.url
      this.isBlobUrl = params.isBlobUrl || this.isBlobUrl
    }
    // 如果存在设置
    if (params.options) {
      this.options = Object.assign({}, this.options, params.options)
    }
    this.promise = this.init()
  }
  /**获取pdf */
  static GetPdf (params: {
    file?: File,
    url?: string,
    isBlobUrl?: boolean,
    options?: {
      scale?: number
    }
  }) {
    return new CddPdf(params).promise
  }

  /**初始化数据 */
  async init () {
    // 获取数据
    const data = await this.getData()
    //转化成图片
    this.imgs = orderBy(await this.parsePdf(data) as any, [ 'pageNumber' ])
    console.log(`over`, this.imgs)
    return this
    // 渲染pdf
  }

  /**获取数据 */
  getData () {
    return new Promise((reso, reg) => {
      if (this.file) {
        const reader = new FileReader()
        reader.onload = (e: any) => reso(e.target.result)
        reader.readAsDataURL(this.file)
      } else if (this.url) {
        reso(this.fetchFile(this.url))
      }
    })
  }

  /**fetc获取文件内容 */
  fetchFile (url: string) {
    return new Promise((reso, rej) => {
      if (url && url.startsWith('http')) {
        /**获取数据 */
        fetch(url).then(async (res) => {
          const blob = await res.blob()
          reso(URL.createObjectURL(blob))
        })
      } else {
        reso(url)
      }
    })
  }
  /**解析pdf文件 */
  async parsePdf (file: any) {
    try {
      return new Promise((reso, rej) => {
        const loadingTask = pdfjs.getDocument(file)
        const arr: any[] = []
        let count = 0
        if (loadingTask.promise) {
          loadingTask.promise.then(pdf => {
            if (pdf && pdf.numPages) {
              for (let i = 1; i <= pdf.numPages; i++) {
                pdf.getPage(i).then(async (page) => {
                  arr.push(await this.renderPage(page))
                  count++
                  if (count === pdf.numPages) {
                    reso(arr)
                  }
                })
              }
            }
          })
        }
      })
    } catch (error) {
      console.error(`渲染出错`, error)
    }
  }

  /**渲染页面 */
  renderPage (page: any) {
    return new Promise((reso, rej) => {
      const viewport = page.getViewport({scale: this.options.scale})
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')

      canvas.height = viewport.height
      canvas.width = viewport.width

      const renderContext = {
        canvasContext: ctx,
        viewport: viewport
      }
      //进行渲染
      page.render(renderContext).promise.then((res: any) => {
        if (this.isBlobUrl) {
          canvas.toBlob((blob) => {
            reso({
              pageNumber: page.pageNumber,
              // value: canvas.toDataURL('image/png', 1)
              value: URL.createObjectURL(blob)
            })
          }, 'image/png', 1)
        } else {
          reso({
            pageNumber: page.pageNumber,
            value: canvas.toDataURL('image/png', 1)
          })
        }
      })
    })
  }
}
